home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************\
- * *
- * LOADGAME.C *
- * *
- * Copyright 1993, 1995 Diana Gruber. All Rights Reserved. *
- * Last modified: April 10, 1995 *
- * *
- * This source code is provided "as is" without any warranties, etc. *
- * *
- * Load the data files, initialize the graphics environment, handle *
- * text, termination, and some other miscellaneous functions. *
- * This file contains just about all the functions that are not *
- * critical to game animation. Those functions are all in the file *
- * QF.C. They are grouped in a single source code file so they can *
- * be declared "near" for a slight speed boost. Functions in this *
- * file are assumed to be far if compiled in real mode using the *
- * medium model. *
- * *
- * For readibility, functions are stored alphabetically. *
- * *
- \**********************************************************************/
-
- #define loadgame
- #include "defs.h"
-
- /**********************************************************************\
- * *
- * clear_layout *
- * Set the layout array to all zeros *
- * *
- \**********************************************************************/
-
- void clear_layout()
- {
- register short i,j;
- for (i = 0; i < 22; i++)
- for (j = 0; j < 15; j++)
- layout[hidden][i][j] = FALSE;
- }
-
- /**********************************************************************\
- * *
- * fcopy_array *
- * copy a string from far memory to near memory *
- * (unnecessary in protected mode) *
- * *
- \**********************************************************************/
-
- void fcopy_array(char far *s, char *t, short nchar)
- {
- register short i;
-
- for (i = 0; i < nchar; i++)
- *s++ = *t++;
- }
-
- /**********************************************************************\
- * *
- * getseed -- get a seed for the random number generator *
- * *
- \**********************************************************************/
-
- void getseed()
- {
- seed = (short)(fg_getclock() & 0x7FFF);
- }
-
- /**********************************************************************\
- * *
- * init_globals *
- * create player and score objects and initialize some global *
- * variables *
- * *
- \**********************************************************************/
-
- void init_globals()
- {
- char *array;
- SPRITE *image;
-
- /* create the score object */
-
- array = (char *)malloc(60*5+1);
- score = (OBJp)malloc(sizeof(OBJ)+1);
- score->action = &new_score; /* does this work? integer address requires "near" declaration
- which means it should be in the same source code file. Hmmm */
- image = (SPRITE *)malloc(sizeof(SPRITE)+1);
- image->bitmap = array;
- image->height = 5;
- image->width = 60;
- image->xoffset = 0;
- image->yoffset = 0;
- score->image = image;
-
- /* create the player object */
- player = (OBJp)malloc(sizeof(OBJ)+1);
- player->x = 26;
- player->y = 164;
- player->frame = 0;
- player->xspeed = -8;
- player->max_xspeed = 8;
- player->yspeed = 0;
- player->tile_xmin = 2;
- player->tile_xmax = 16;
- player->tile_ymin = 5;
- player->attached_sprite = (OBJp)NULL;
- player->tile_ymax = 10;
- player->image = fighter[0];
-
- /* initialize some global variables */
- player_timer = 0;
- player_time_target = 75;
- bullet_count = 0;
- nhits = 0;
- hit_value = 990;
- player_score = 0L;
- scrolled = FALSE;
- frame_count = 0;
- nbullets = 0;
- nenemies = 0;
- autopilot = FALSE;
-
- /* origin coordinates */
- tile_orgx = 0;
- tile_orgy = 0;
- screen_orgx = 0;
- screen_orgy = 0;
- vpo = 0;
- hpo = 240;
- vpb = vpo+239;
- hpb = hpo+239;
- tpo = 480;
- visual = 0;
- hidden = 1;
-
- /* start the random number generator */
- getseed();
- }
-
- /**********************************************************************\
- * *
- * init_graphics -- initialize the graphics environment *
- * *
- \**********************************************************************/
-
- void init_graphics()
- {
- #ifdef ModeX
- fg_setmode(20); /* Mode X at a 320*200 resolution */
- fg_resize(352,727);
- #else
- fg_setmode(19); /* Mode 13h */
- fg_vbinit();
- if ((virtbuff1 = (char *)malloc(352*727)) == (char *)NULL)
- {
- sprintf(abort_string,"out of virtual buffer memory");
- terminate_game();
- }
- workvb = fg_vbdefine(virtbuff1,352,727);
- fg_vbopen(workvb);
- #endif
-
- /* uncomment this line to turn off the vertical retrace */
- // fg_waitvr(0);
- }
-
- /**********************************************************************\
- * *
- * intro_screens *
- * Display the title screen and the credits screen *
- * *
- \**********************************************************************/
-
- void intro_screens()
- {
- register short i;
- char *array;
- short x;
-
- /* display title screen, copy to visual */
- fg_move(0,hpo);
- #ifdef ModeX
- fg_showpcx("qf1.pcx",2);
- fg_transfer(0,319,hpo,hpb,0,vpb,0,0);
- #else
- fg_loadpcx("qf1.pcx",2);
- fg_vbpaste(0,319,hpo,hpo+199,0,199);
- #endif
- fg_waitfor(32);
- }
-
- /**********************************************************************\
- * *
- * irandom *
- * Generate a pseudo-random number between any two integers. *
- * *
- \**********************************************************************/
-
- irandom(short min, short max)
- {
- register short temp;
-
- temp = seed ^ (seed >> 7);
- seed = ((temp << 8) ^ temp) & 0x7FFF;
- return((seed % (max-min+1)) + min);
- }
-
- /**********************************************************************\
- * *
- * load_level *
- * Read the level information from a file *
- * *
- \**********************************************************************/
-
- void load_level()
- {
- register short i,j;
- char buffer[MAXROWS];
-
- fg_move(0,480);
- #ifdef ModeX
- /* display the pcx file containing the tiles */
- fg_showpcx("QF.PCX",2);
- #else
- /* load the pcx file containing the tiles into a virtual buffer*/
- fg_loadpcx("QF.PCX",2);
- #endif
- /* open the level file containing the map information */
-
- if ((tstream = fopen("QF.LEV","rb")) == NULL)
- {
- sprintf(abort_string,"QF.LEV not found");
- terminate_game();
- }
-
- /* read the number of rows and columns */
- fread(&ncols,sizeof(short),1,tstream);
- fread(&nrows,sizeof(short),1,tstream);
-
- /* read all the rows */
- for (i = 0; i < ncols; i++)
- {
- fread(buffer,sizeof(char),nrows,tstream);
- fcopy_array(&backtile[i][0],buffer,nrows);
- }
- fclose(tstream);
-
- /* rows must be even -- adjust for odd number of rows */
- if (ncols%2 != 0)
- ncols--;
-
- /* calculate the maximum world coordinates */
- world_maxx = ncols*16-1;
- world_maxy = nrows*16-1;
-
- /* add another 22 columns at the end of the array for circular scroll */
- for (i = 0; i < 22; i++)
- {
- for (j = 0; j < nrows; j++)
- backtile[ncols+i][j] = backtile[i+54][j];
- }
- ncols+=22;
- }
-
- /**********************************************************************\
- * *
- * load_sprite *
- * Read the bitmapped sprites from a file and store them in *
- * structures. *
- * *
- \**********************************************************************/
-
- void load_sprite()
- {
- register short i,n;
- short nbytes;
- char *bitmap;
- short width,height;
- SPRITE *new_sprite;
-
- /* open the bitmap file i you can find it */
- if ((tstream = fopen("QF.BMP","rb")) == NULL)
- {
- sprintf(abort_string,"QF.BMP not found");
- terminate_game();
- }
-
- i = 0;
-
- /* how many sprites are we talking about? */
- fread(&nsprites,sizeof(short),1,tstream);
-
- /* read all the sprites */
- for (n = 0; n < nsprites; n++)
- {
- /* read the width and height and calculate the size of the bitmap */
- fread(&width,sizeof(short),1,tstream);
- fread(&height,sizeof(short),1,tstream);
- nbytes = width * height;
-
- /* allocate space for the bitmap */
- if ((bitmap = (char *)malloc(nbytes)) == (char *)NULL)
- {
- sprintf(abort_string,"nsprites=%d n=%d width=%d height=%d nbytes=%d\n",
- nsprites,n,width, height, nbytes);
- terminate_game();
- }
-
- /* allocate space for the sprite, which is a structure including
- the pointer to the previously allocated bitmap */
- if ((new_sprite = (SPRITE *)malloc(sizeof(SPRITE)+1)) == (SPRITE *)NULL)
- {
- sprintf(abort_string,"Out of sprite memory");
- terminate_game();
- }
-
- /* put this pointer in the sprite array */
- sprite[i] = new_sprite;
-
- /* now read the bitmap */
- fread(bitmap,sizeof(char),nbytes,tstream);
-
- /* initialize the sprite variables */
- sprite[i]->bitmap = bitmap;
- sprite[i]->width = width;
- sprite[i]->height = height;
- sprite[i]->xoffset = 0;
- sprite[i]->yoffset = 0;
- i++;
- }
- fclose(tstream);
-
- /* assign sprites to the fighter arrays and give them y offsets */
- fighter[0] = sprite[0];
- fighter[1] = sprite[9];
- fighter[2] = sprite[1];
- fighter[3] = sprite[10];
- fighter[4] = sprite[3];
- fighter[5] = sprite[11];
- fighter[6] = sprite[2];
- fighter[7] = sprite[12];
-
- /* also create an explosion array */
- for (i = 0; i < 11; i++)
- explosion[i] = sprite[i+14];
-
- /* center the fighter */
- for (i = 0; i < 8; i++)
- {
- fighter[i]->yoffset = fighter[i]->height/2 - fighter[2]->height/2;
- }
-
- /* center the explosions */
- for (i = 1; i < 11; i++)
- {
- explosion[i]->xoffset = explosion[0]->width - explosion[i]->width/2;
- explosion[i]->yoffset = explosion[i]->height/2 - explosion[0]->height;
- }
- }
-
- /**********************************************************************\
- * *
- * put_btext *
- * *
- * This is a simple, efficient character font. Capital letters only. *
- * Not all the characters are included, only the ones we need. *
- * The letters are defined as 5 x 5 single color bitmaps. *
- * *
- \**********************************************************************/
-
- char chars[37][5] = {
- 0, 0, 0, 0, 0,
- -120, -8,-120, 80, 32, /* a */
- -16,-120, -16,-120, -16, /* b */
- 120,-128,-128,-128, 120, /* c */
- -16,-120,-120,-120, -16, /* c */
- -8,-128, -16,-128, -8, /* e */
- -128,-128, -16,-128, -16, /* f */
- 112,-120,-104,-128, 120, /* g */
- -120,-120, -8,-120,-120, /* h */
- 112, 32, 32, 32, 112, /* i */
- 96,-112, 16, 16, 56, /* j */
- -120,-112, -32,-112,-120, /* k */
- -8,-128,-128,-128,-128, /* l */
- -120, -88, -88, -40,-120, /* m */
- -120,-104, -88, -56,-120, /* n */
- 112,-120,-120,-120, 112, /* o */
- -128,-128, -16,-120, -16, /* p */
- 120, -88,-120,-120, 112, /* q */
- -112, -96, -16,-120, -16, /* r */
- -16, 8, 112,-128, 120, /* s */
- 32, 32, 32, 32, -8, /* t */
- 112,-120,-120,-120,-120, /* u */
- 32, 80,-120,-120,-120, /* v */
- -120, -40, -88, -88,-120, /* w */
- -120, 80, 32, 80,-120, /* x */
- 32, 32, 32, 80,-120, /* y */
- -8, 64, 32, 16, -8, /* x */
- 112,-120,-120,-120, 112, /* 0 */
- 112, 32, 32, 96, 32, /* 1 */
- -16, 64, 32,-112, 96, /* 2 */
- -32, 16, 96, 16, -32, /* 3 */
- 16, 16, -16,-112,-112, /* 4 */
- 112, 8, -16,-128, -8, /* 5 */
- 112,-120, -16,-128, 112, /* 6 */
- 64, 64, 32, 16, -8, /* 7 */
- 112,-120, 112,-120, 112, /* 8 */
- 16, 8, 120,-120, 112, /* 9 */
- };
-
- put_bstring(char *string,short nchar,short ix,short iy)
- {
- register short i;
- short blank;
- char ch;
-
- for (i = 0; i < nchar; i++)
- {
- blank = FALSE;
- ch = string[i];
-
- /* upper case */
- if (ch >= 65 && ch <= 90)
- ch -= 64;
-
- /* lower case */
- else if (ch >= 97 && ch <= 122)
- ch -= 96;
-
- /* numbers */
- else if (ch >= 48 && ch <= 57)
- ch -= 21;
-
- else
- blank = TRUE;
-
- fg_move(ix,iy);
- if (!blank) fg_drawmap(&chars[ch][0],1,5);
- ix += 6;
- }
- return(0);
- }
-
- /**********************************************************************\
- * *
- * terminate_game *
- * If for some reason we can't continue, like for example if a data *
- * file is missing, do an abnormal termination. *
- * *
- \**********************************************************************/
-
- void terminate_game()
- {
- /* disable the keyboard handler */
- fg_kbinit(0);
-
- /* close the virtual buffers */
- fg_vbclose();
-
- /* set the video mode to text mode */
- fg_setmode(3);
-
- /* reset the screen attributes (if ANSI.SYS is loaded ) */
- fg_reset();
-
- /* print the exit screen and exit */
- printf(abort_string);
- printf("\n");
- exit(0);
- }
-